Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AVRO-2825: [csharp] Resolve: C# Logical Types throw exception on unknown logical type #2741

Closed
wants to merge 4 commits into from

Conversation

TomBruns
Copy link

AVRO-2825

What is the purpose of the change

  • This pull request resolves an outstanding issue with the csharp implementation behavior that is not consistent with the AVRO spec and the java behavior.
  • Per the AVRO Spec:
    • Language implementations must ignore unknown logical types when reading, and should use the underlying Avro type
  • The current csharp implementation throws an exception for unrecognized Logical Types.

NOTE: This PR WILL change the behavior of the current nuget package. It corrects it to align with the AVRO spec.

Verifying this change

This change is already covered by existing tests:

  • test > AvroGen > AvroGenSchemaTests.cs > NotSupportedSchema

    • corrected expected result of Test
  • test > Schema > SchemaTests.cs > TestUnknownLogical

    • corrected expected result of Test

This change added tests and can be verified as follows:

  • test > Util > LogicalTypeTests.cs > TestUnknownLogicalType
    • added more complex test to confirm underlying AVRO base type is used.

Documentation

  • Does this pull request introduce a new feature? (no)

Tom Bruns added 3 commits February 16, 2024 07:42
 Language implementations must ignore unknown logical types when reading, and should use the underlying Avro type.
also resolved exception thrown if namespace is missing from schema
@github-actions github-actions bot added the C# label Feb 16, 2024
… the schema file does not contain a namespace

This reverts commit 3f75a9a.
Comment on lines +195 to +202
try
{
if (null != jo["logicalType"]) // logical type based on a primitive
return LogicalSchema.NewInstance(jtok, props, names, encspace);
}
// swallow exception from unknown logicalType
catch { }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can LogicalSchema.NewInstance instead be made to work with unrecognized logical types? For these purposes:

  • Avoid swallowing any exceptions thrown for other reasons.
  • Allow applications to parse a schema and read the name of the logical type from LogicalSchema.LogicalTypeName (or even LogicalType.Name) regardless of whether the library recognizes it.
  • Allow applications to parse a schema and serialize it back to JSON without losing the unrecognized logical types here:
    private static readonly HashSet<string> ReservedProps = new HashSet<string>() { "type", "name", "namespace", "fields", "items", "size", "symbols", "values", "aliases", "order", "doc", "default", "logicalType" };
    if (ReservedProps.Contains(prop.Name))
    continue;

LogicalSchema.LogicalType could then be null, or perhaps an instance of a new NotSupportedLogicalType class that would pass everything through without conversion.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will work on that, thanks for the feedback

Comment on lines -896 to +903
if (string.IsNullOrEmpty(nspace))
{
throw new CodeGenException("Namespace required for record schema " + recordSchema.Name);
}

CodeNamespace codens = AddNamespace(nspace);

//if (string.IsNullOrEmpty(nspace))
//{
// throw new CodeGenException("Namespace required for record schema " + recordSchema.Name);
//}

// AVRO spec DOES NOT require a Namespace but this code does.
// Workaround is to inject a fixed string that will be obvious if required
CodeNamespace codens = (!string.IsNullOrEmpty(nspace)) ? AddNamespace(nspace) : AddNamespace(@"SchemaHadNoNamespace");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not related to logical types. Please move to a separate pull request.

return LogicalSchema.NewInstance(jtok, props, names, encspace);
}
// swallow exception from unknown logicalType
catch { }

Check notice

Code scanning / CodeQL

Generic catch clause Note

Generic catch clause.
return LogicalSchema.NewInstance(jtok, props, names, encspace);
}
// swallow exception from unknown logicalType
catch { }

Check notice

Code scanning / CodeQL

Poor error handling: empty catch block Note

Poor error handling: empty catch block.
var secondField = ((RecordSchema)schema).Fields.FirstOrDefault(f => f.Name == @"secondField");
Assert.IsNotNull(secondField);

var secondFieldSchema = ((Field)secondField).Schema;

Check warning

Code scanning / CodeQL

Cast to same type Warning test

This cast is redundant because the expression already has type Field.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants